package com.yimin.floatball

import android.accessibilityservice.AccessibilityService
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.os.Vibrator
import android.os.VibratorManager
import android.util.Log
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewTreeObserver
import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.ImageView
import com.yimin.floatball.databinding.FloatBallBinding
import com.yimin.floatball.util.AccessibilityUtil
import com.yimin.floatball.util.CommonUtil
import kotlin.math.abs


class FloatBallView(context: Context) : FrameLayout(context) {
    private lateinit var mLayoutParams: WindowManager.LayoutParams

    /**
     * 按下时间，用于辅助判断是否为长按
     */
    private var mLastDownTime: Long = 0
    private var mLastDownX: Float = 0f
    private var mLastDownY: Float = 0f

    private var mIsLongTouch: Boolean = false

    /**
     * 是否正在触摸
     */
    private var mIsTouching: Boolean = false

    /**
     * 滑动的阈值
     */
    private var mTouchSlop: Int = 0


    private var mStatusBarHeight: Int = 0
    private var mService: AccessibilityService
    private var mCurrentMode: Int = MODE_NONE

    /**
     * 进行手势操作（上下左右，控制大球相对于背景的位置偏移）
     * 实际上就是大球的getX()
     */
    private var OFFSET: Float = 0f

    /**
     * 大球在view内的坐标
     */
    private var mBigBallX: Float = 0f
    private var mBigBallY: Float = 0f

    /**
     * 移动view位置计算时，需要减去的偏移量
     */
    private var mOffsetToParent: Int = 0
    private var mOffsetToParentY: Int = 0
    private val mPattern = longArrayOf(0, 50)

    /**
     * 窗口
     */
    private lateinit var mWindowManager: WindowManager

    /**
     * 震动
     */
    private lateinit var mVibrator: Vibrator

    private val binding: FloatBallBinding

    companion object {
        const val MODE_NONE = 0x000
        const val MODE_DOWN = 0x001
        const val MODE_UP = 0x002
        const val MODE_LEFT = 0x003
        const val MODE_RIGHT = 0x004
        const val MODE_MOVE = 0x005
        const val MODE_GONE = 0x006

        const val LONG_CLICK_LIMIT: Long = 300
        const val REMOVE_LIMIT: Long = 1500
        const val CLICK_LIMIT: Long = 200
    }


    init {
        binding = FloatBallBinding.inflate(LayoutInflater.from(context))
        addView(binding.root)

        mTouchSlop = ViewConfiguration.get(getContext()).scaledTouchSlop
        Log.d(TAG, "mTouchSlop: ${mTouchSlop}")

        mStatusBarHeight = CommonUtil.getStatusBarHeight();
        mOffsetToParent = CommonUtil.dip2px(25f);

        Log.d(TAG, "mOffsetToParent: ${mOffsetToParent}")
        mOffsetToParentY = mStatusBarHeight + mOffsetToParent;

        // mBigBallX = binding.imgBigBall.x;
        // mBigBallY = binding.imgBigBall.y;
        Log.d(TAG, "mBigBallX:${mBigBallX}, mBigBallY:${mBigBallY}")
        Log.d(TAG, "mBallX:${binding.imgBall.x}, mBallY:${binding.imgBall.y}") // 0不能在这获取

        mService = context as AccessibilityService
        initManager()

        // 所有视图确定位置和尺寸时触发
        // 在这里可以安全的访问视图的位置和尺寸
        viewTreeObserver.addOnGlobalLayoutListener(object :
            ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                // 只需要调用一次
                viewTreeObserver.removeOnGlobalLayoutListener(this)
                mBigBallX = binding.imgBigBall.x;
                mBigBallY = binding.imgBigBall.y;
                OFFSET = binding.imgBigBall.x
                Log.d(TAG, "viewTreeObserver mBallX:${mBigBallX}, mBallY:${mBigBallY}")
                Log.d(TAG, "OFFSET: ${OFFSET}")
                Log.d(TAG, "viewTreeObserver width: ${binding.imgBigBall.width}")
            }
        })

    }


    private fun initManager() {
        mWindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        mVibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d(TAG, "ACTION_DOWN")
                // 正在触摸
                mIsTouching = true

                // 显示出大球，隐藏小球
                binding.imgBall.visibility = INVISIBLE
                binding.imgBigBall.visibility = VISIBLE

                // 记录按下的时间，坐标
                mLastDownTime = System.currentTimeMillis()
                mLastDownX = event.x
                mLastDownY = event.y

                // 指定时间后还在触摸，认为是长按动作
                postDelayed({
                    if (isLongTouch()) {
                        Log.d(TAG, "ACTION_DOWN,isLongTouch: true")
                        mIsLongTouch = true
                        mVibrator.vibrate(mPattern, -1)
                    }
                }, LONG_CLICK_LIMIT)
            }

            MotionEvent.ACTION_MOVE -> {
                // move的前提是长按，否则不触发
                if (!mIsLongTouch && isTouchSlop(event)) return true
                // 当前处于长按状态（移动或者没有移动），可以进行移动
                if (mIsLongTouch && (mCurrentMode == MODE_NONE || mCurrentMode == MODE_MOVE)) {
                    mLayoutParams.x = (event.rawX - mOffsetToParent).toInt()
                    mLayoutParams.y = (event.rawY - mOffsetToParentY).toInt()
                    mWindowManager.updateViewLayout(this@FloatBallView, mLayoutParams)
                    // mBigBallX = binding.imgBigBall.x
                    // mBigBallY = binding.imgBigBall.y
                    Log.d(TAG, "mBigBallX:${mBigBallX}, mBigBallY:${mBigBallY}")
                    Log.d(TAG, "mBallX:${binding.imgBall.x}, mBallY:${binding.imgBall.y}")
                    mCurrentMode = MODE_MOVE
                } else {
                    doGesture(event)
                }
            }

            MotionEvent.ACTION_CANCEL,
            MotionEvent.ACTION_UP -> {
                // 停止触摸
                mIsTouching = false
                if (mIsLongTouch) {// 长按
                    mIsLongTouch = false
                } else if (isClick(event)) { // 判定为点击
                    AccessibilityUtil.doBack(mService)
                    performClick()
                } else {// 执行动作后松手
                    doUp()
                    // 大球位置复原
                    binding.imgBigBall.x = mBigBallX
                    binding.imgBigBall.y = mBigBallY
                }
                // 大球隐藏，小球出现
                binding.imgBall.visibility = VISIBLE
                binding.imgBigBall.visibility = INVISIBLE
                // 状态重置
                mCurrentMode = MODE_NONE

            }
        }
        return true
    }

    override fun performClick(): Boolean {
        return super.performClick()
    }


    /**
     * 是否是长按
     * [mCurrentMode]初始值和停止触摸时，都为[MODE_NONE]
     */
    private fun isLongTouch(): Boolean {
        val time = System.currentTimeMillis()
        return mIsTouching && mCurrentMode == MODE_NONE && time - mLastDownTime >= LONG_CLICK_LIMIT
    }

    private fun toRemove() {
        mVibrator.vibrate(mPattern, -1)
        FloatWindowManager.removeBallView(context)
    }

    /**
     * 是否判定为滑动事件，滑动距离必须大于阈值[mTouchSlop]
     */
    private fun isTouchSlop(event: MotionEvent): Boolean {
        val x = event.x
        val y = event.y
        return abs(x - mLastDownX) < mTouchSlop && abs(y - mLastDownY) < mTouchSlop
    }

    private fun doGesture(event: MotionEvent) {
        val offsetX = event.x - mLastDownX
        val offsetY = event.y - mLastDownY

        if (abs(offsetX) < mTouchSlop && abs(offsetY) < mTouchSlop) return

        // 主要是左右移动
        if (abs(offsetX) > abs(offsetY)) {
            if (offsetX > 0) {// 右
                if (mCurrentMode == MODE_RIGHT) return
                mCurrentMode = MODE_RIGHT
                binding.imgBigBall.x = mBigBallX + OFFSET
                binding.imgBigBall.y = mBigBallY
            } else {// 左
                if (mCurrentMode == MODE_LEFT) return
                mCurrentMode = MODE_LEFT
                binding.imgBigBall.x = mBigBallX - OFFSET
                binding.imgBigBall.y = mBigBallY
            }
        } else { // 上下移动
            if (offsetY > 0) { // 下
                if (mCurrentMode == MODE_DOWN || mCurrentMode == MODE_GONE) return
                mCurrentMode = MODE_DOWN
                binding.imgBigBall.x = mBigBallX
                binding.imgBigBall.y = mBigBallY + OFFSET
                // postDelayed({ // 下滑长按1.5s后移除
                //     if (mCurrentMode == MODE_DOWN && mIsTouching) {
                //         toRemove()
                //         mCurrentMode = MODE_GONE
                //     }
                // }, REMOVE_LIMIT)
            } else {// 上
                if (mCurrentMode == MODE_UP) return
                mCurrentMode = MODE_UP
                binding.imgBigBall.x = mBigBallX
                binding.imgBigBall.y = mBigBallY - OFFSET
            }
        }
    }

    private fun doUp() {
        when (mCurrentMode) {
            MODE_LEFT, MODE_RIGHT -> AccessibilityUtil.doLeftOrRight(mService)
            MODE_DOWN -> AccessibilityUtil.doPullDown(mService)
            MODE_UP -> AccessibilityUtil.doPullUp(mService)
        }
    }

    fun setLayoutParams(params: WindowManager.LayoutParams) {
        mLayoutParams = params
    }

    private fun isClick(event: MotionEvent): Boolean {
        val offsetX = abs(event.x - mLastDownX)
        val offsetY = abs(event.y - mLastDownY)
        val time = System.currentTimeMillis() - mLastDownTime

        return offsetX < mTouchSlop * 2 && offsetY < mTouchSlop * 2 && time < CLICK_LIMIT
    }


}